/*
 * 文件名： AggregatePayPabSericeImpl.java
 * 
 * 工程名称: bis-service
 *
 * Gopay
 *
 * 创建日期： 2017年8月10日
 *
 * Copyright(C) 2017, by www.gopay.com.cn Inc.All rights reserved.
 *
 * 原始作者: 宣广海
 *
 */
package com.gopay.bis.service.bank.impl.scan;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.manager.bank.scan.ScanPayPabManager;
import com.gopay.bis.service.bank.BankIntrChannConfService;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.pab.agpay.PabTransResMsg;
import com.gopay.common.domain.bank.pab.agpay.req.MerchantConfig;
import com.gopay.common.domain.bank.pab.agpay.res.MerchantAddResMsg;
import com.gopay.common.domain.bank.pab.agpay.res.PayOrderResMsg;
import com.gopay.common.domain.bank.pab.agpay.res.PayRefundQueryResMsg;
import com.gopay.common.domain.bank.pab.agpay.res.PayRefundResMsg;
import com.gopay.common.domain.bank.pab.agpay.res.PayStatusResMsg;
import com.gopay.common.domain.bank.wechat.scan.cmbc.FileDownReq;
import com.gopay.common.domain.bank.wechat.scan.cmbc.MerchantOperation;
import com.gopay.common.domain.bank.wechat.scan.cmbc.MerchantSettled;
import com.gopay.common.domain.bank.wechat.scan.res.ScanPayResultMsg;
import com.gopay.common.domain.bank.wechat.scan.res.ScanPayServerNotifyMsg;
import com.gopay.common.domain.bis.BaseBisBankExtConfig;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.TransUtil;
import com.gopay.remote.bank.ScanPayInteractRemoteService;
import com.gopay.remote.bank.ScanPayMerchantService;

/**
 * 聚合支付平安银行渠道
 *
 * @author 宣广海
 *
 * @version
 *
 * @since 2017年8月10日
 */
public class ScanPayPabSericeImpl implements ScanPayInteractRemoteService, ScanPayMerchantService {
	/**
	 * 日志对象
	 */
	private static Logger logger = LoggerFactory.getLogger(ScanPayPabSericeImpl.class);

	@Resource(name = "scanPayPabManager")
	private ScanPayPabManager scanPayPabManager;
	@Resource(name = "bankIntrChannConfService")
	private BankIntrChannConfService bankIntrChannConfService;

	@Override
	public Result pay(BaseMessage msg) throws GopayException {
		logger.info("------------ScanPayPabSericeImpl pay start-------------");
		long beginTime = System.currentTimeMillis();
		/**
		 * 定义返回对象
		 */
		Result result = new Result(false);
		try {
			@SuppressWarnings("unchecked")
			PabTransResMsg<PayOrderResMsg> resMessage = (PabTransResMsg<PayOrderResMsg>) scanPayPabManager.scanPay(msg);
			/**
			 * 定义扫码返回对象
			 */
			ScanPayResultMsg respMsg = new ScanPayResultMsg();
			PayOrderResMsg scanPayResult = (PayOrderResMsg) resMessage.getBody();
			if (StringUtils.equalsIgnoreCase("0", resMessage.getErrcode())
					&& StringUtils.isNotBlank(scanPayResult.getTrade_qrcode())) {
				BeanUtils.copyProperties(resMessage, respMsg);

				respMsg.setCodeUrl(scanPayResult.getTrade_qrcode());
				respMsg.setCodeImage(scanPayResult.getTrade_qrcode());

				respMsg.setCode_url(scanPayResult.getTrade_qrcode());
				respMsg.setCode_img_url(scanPayResult.getTrade_qrcode());

				result.setDefaultModel(respMsg); // 收银台从ScanPayBaseMessage类获取支付请求结果
				result.setSuccess(true);
			} else {
				result.setResultCode(ProcCodeConstants.PROC_CODE_100E1161);
				result.setErrorMsg(resMessage.getMsg());
				result.setSuccess(false);
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E1161);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ ScanPayPabSericeImpl pay end，耗时(ms):" + (endTime - beginTime));
		return result;

	}

	@Override
	public Result orderQuery(BaseMessage msg) throws GopayException {

		logger.info("------------ScanPayPabSericeImpl orderQuery start-------------");
		long beginTime = System.currentTimeMillis();
		/**
		 * 定义返回对象
		 */
		Result result = new Result();
		try {
			@SuppressWarnings({ "unchecked" })
			PabTransResMsg<PayStatusResMsg> resMessage = (PabTransResMsg<PayStatusResMsg>) scanPayPabManager
					.orderQuery(msg);
			if (("".equals(resMessage.getBody().getTrade_amount()))
					|| (null == resMessage.getBody().getTrade_amount())) {
				resMessage.setAmount(msg.getAmount());
			} else {
				resMessage.setAmount(new BigDecimal(
						TransUtil.amountConvert2Yuan(String.valueOf(resMessage.getBody().getTrade_amount()))));
			}
			result.setDefaultModel(resMessage);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ ScanPayPabSericeImpl orderQuery end，耗时(ms):" + (endTime - beginTime));
		return result;

	}

	@Override
	public Result refund(BaseMessage msg) throws GopayException {

		logger.info("------------ScanPayPabSericeImpl refund start-------------");
		long beginTime = System.currentTimeMillis();
		/**
		 * 定义返回对象
		 */
		Result result = new Result(false);
		try {
			@SuppressWarnings("unchecked")
			PabTransResMsg<PayRefundResMsg> resMsg = (PabTransResMsg<PayRefundResMsg>) scanPayPabManager.refund(msg);
			if (resMsg != null) {
				if ("0".equals(resMsg.getErrcode()) && "0".equals(resMsg.getBody().getStatus())) {
					result.setDefaultModel(resMsg);
					result.setSuccess(true);
					// 接收成功
					result.setModel("falg", true);
				} else {
					result.setSuccess(false);
					result.setModel("falg", false);
					result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
					result.setErrorMsg(resMsg.getMsg());
				}
			} else {
				result.setSuccess(false);
				result.setModel("falg", false);
				result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
			}

		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ ScanPayPabSericeImpl refund end，耗时(ms):" + (endTime - beginTime));
		return result;

	}

	@Override
	public Result refundQuery(BaseMessage msg) throws GopayException {
		logger.info("------------ScanPayPabSericeImpl refundQuery start-------------");
		long beginTime = System.currentTimeMillis();
		/**
		 * 定义返回对象
		 */
		Result result = new Result();
		try {
			@SuppressWarnings({ "unchecked" })
			PabTransResMsg<PayRefundQueryResMsg> resMessage = (PabTransResMsg<PayRefundQueryResMsg>) scanPayPabManager
					.refundOrderQuery(msg);
			resMessage.setAmount(msg.getAmount());
			result.setDefaultModel(resMessage);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ ScanPayPabSericeImpl refundQuery end，耗时(ms):" + (endTime - beginTime));
		return result;
	}

	@Override
	public Result verify(BaseMessage msg) throws GopayException {
		Result result = new Result(false);
		try {
			ScanPayServerNotifyMsg message = (ScanPayServerNotifyMsg) msg;
			Boolean flag = (Boolean) scanPayPabManager.verify(message);
			result.setDefaultModel(flag);
			result.setSuccess(true);
			result.setModel("res", message);
			Map<String, String> param = new HashMap<String, String>();
			/**
			 * 验签成功
			 */
			if ((boolean) result.getDefaultModel()) {
				if (("0".equals(message.getPay_result()))) {
					param.put("orderId", message.getOrderId());
					param.put("amt", String.valueOf(message.getAmount()));
					param.put("cardType", "Unknown");
					param.put("notifyNum", "1");
					param.put("payStatus", "00");
					param.put("retCode", "00");
					param.put("retMsg", "验签成功");
					param.put("signData", "");
					param.put("isFront", String.valueOf(message.isFront()));
					result.setModel("isNotifyCashier", param);
					result.setOrderStatus(true);
				} else {
					param.put("orderId", message.getOrderId());
					param.put("amt", String.valueOf(message.getAmount()));
					param.put("cardType", "Unknown");
					param.put("notifyNum", "1");
					param.put("payStatus", "01");
					param.put("retCode", "01");
					param.put("retMsg", "验签失败");
					param.put("signData", "");
					param.put("isFront", String.valueOf(message.isFront()));
					result.setModel("isNotifyCashier", param);
					result.setOrderStatus(false);
				}
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6064);
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Result merchantSettled(Object msg) throws GopayException {
		BaseBisBankExtConfig bankConfig = bankIntrChannConfService.findBaseBisBankExtConfigByBankChannel(
				BisBankBusinessProd._16, BisBankInterfaceChannel._25, BankConstants.BANK_LOGO_WECHAT);
		MerchantSettled request = (MerchantSettled) msg;
		PabTransResMsg<MerchantAddResMsg> response = (PabTransResMsg<MerchantAddResMsg>) scanPayPabManager
				.merchantSettled(request, generateParam(bankConfig));
		logger.info("---平安银行商户入驻返回处理对象：" + ToStringBuilder.reflectionToString(response));
		Result result = new Result();
		if (StringUtils.equalsIgnoreCase("0", response.getErrcode())) {
			result.setSuccess(true);
			result.setOrderStatus(true);
			MerchantSettled resObj = new MerchantSettled();
			resObj.setMerchantCode(response.getBody().getOpen_id());
			resObj.setMerchantKey(response.getBody().getOpen_key());
			result.setDefaultModel(resObj);
		} else {
			result.setSuccess(false);
			result.setOrderStatus(false);
			result.setErrorMsg(response.getMsg());
			result.setResultCode(response.getErrcode());
		}
		return result;
	}

	@Override
	public Result merchantQuery(Object msg) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result merchantModify(Object msg) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result getCheckAccountFile(FileDownReq obj) throws GopayException {

		BaseBisBankExtConfig bankConfig = bankIntrChannConfService.findBaseBisBankExtConfigByBankChannel(
				BisBankBusinessProd._16, BisBankInterfaceChannel._25, BankConstants.BANK_LOGO_WECHAT);
		Result result = new Result();

		String response = (String) scanPayPabManager.getCheckAccountFile(obj, generateParam(bankConfig));
		if (StringUtils.isNotBlank(response)) {
			result.setSuccess(true);
			result.setDefaultModel(response);
		} else {
			result.setErrorMsg("获取对账文件错误");
			result.setSuccess(false);
		}
		return result;

	}

	@Override
	public Result getCheckAlipayAccountFile(FileDownReq obj) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result merchantOperation(Object msg) throws GopayException {

		BaseBisBankExtConfig bankConfig = bankIntrChannConfService.findBaseBisBankExtConfigByBankChannel(
				BisBankBusinessProd._18, BisBankInterfaceChannel._25, BankConstants.BANK_LOGO_WECHAT);
		MerchantOperation request = (MerchantOperation) msg;
		@SuppressWarnings("rawtypes")
		PabTransResMsg<MerchantConfig> response = (PabTransResMsg<MerchantConfig>) scanPayPabManager
				.merchantOperation(request, generateParam(bankConfig));
		Result result = new Result();

		if (StringUtils.equalsIgnoreCase("0", response.getErrcode())) {
			result.setSuccess(true);
			result.setOrderStatus(true);
			result.setModel("flag", "S");
		} else {
			if ("公众号支付支付域名已存在，请勿重复配置".contains(response.getMsg())|| "subappid已配置，请勿重复配置".contains(response.getMsg())) {
				result.setSuccess(true);
				result.setOrderStatus(true);
				result.setModel("flag", "S");
			} else {
				result.setModel("flag", "E");
				result.setSuccess(true);
				result.setOrderStatus(false);
				result.setErrorMsg(response.getMsg());
				result.setResultCode(response.getErrcode());
			}

		}
		return result;
	}

	@Override
	public Result merchantOperationQuery(Object msg) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}

	public Map<String, String> generateParam(BaseBisBankExtConfig bankConfig) {
		Map<String, String> param = new HashMap<String, String>();
		param.put("merKey", bankConfig.getIntrMerPravkeyPath());
		param.put("merId", bankConfig.getIntrMernum1());
		return param;
	}
}
